package com.dangdang.concurrent;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.function.Supplier;

/**
 * @Author Jiangnan Hou
 * @Date 2022/8/1
 */
public class CompletableFutureDemo {


    public static void main(String[] args) {
        //runAsyncTest();
        //supplyAsyncTest();
        synchronizedTest();
/*        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }*/
        System.out.println("期望最先执行");
        //completeTest();
    }


    public static void runAsyncTest(){
        CompletableFuture<Void> future = CompletableFuture.runAsync(() -> System.out.println("hello word"));
        try {
            System.out.println(future.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

    public static void supplyAsyncTest(){
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> getDataById(10));
        try {
            //System.out.println(future.complete("test complete!"));
            //future.join();
            future.get();

        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

    public static String getDataById(int id){
        System.out.println("getDataById: "+Thread.currentThread().getName());
        return "Data: " + id;
    }


    public static void completeTest(){
        CompletableFuture<String> future = CompletableFuture.supplyAsync(new Supplier<String>() {
            @Override
            public String get() {
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (Exception e) {
                    e.printStackTrace();
                }

                return "blog.csdn.net/zhangphil";
            }
        });

        System.out.println(System.currentTimeMillis() + ":time 1");

        future.whenCompleteAsync(new BiConsumer<String, Throwable>() {
            @Override
            public void accept(String s, Throwable throwable) {
                System.out.println(System.currentTimeMillis() + ":" + s);
            }
        });

        System.out.println(System.currentTimeMillis() + ":time 2");

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (Exception e) {
                    //异常退出。
                    future.completeExceptionally(e);
                }

                // CompletableFuture被通知线程任务完成。
                System.out.println(System.currentTimeMillis() + ":运行至此。");
                future.complete("任务完成。");
            }
        }).start();

        System.out.println(System.currentTimeMillis() + ":time 3");
    }


    private static void synchronizedTest () {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {

            try {
                Thread.sleep(2000l);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "synchronizedTest!";
        });

        try {
            System.out.println(future.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}
